package com.ruoyi.workflow.service.impl;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.workflow.domain.CarPackageAudit;
import com.ruoyi.workflow.domain.vo.CarPackageAuditVo;
import com.ruoyi.workflow.service.IBpmnNodeService;
import com.ruoyi.workflow.service.ICarPackageAuditService;
import com.ruoyi.workflow.service.ITodoTaskService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class TodoTaskServiceImpl implements ITodoTaskService {

    @Autowired
    private TaskService    taskService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private ICarPackageAuditService carPackageAuditService;
    @Autowired
    private IBpmnNodeService bpmnNodeService;
    @Autowired
    private ISysUserService userService;

    /** 查询我的代办任务列表 */
    @Override
    public TableDataInfo selectTodoList(CarPackageAudit carPackageAudit) {
        TableDataInfo info = new TableDataInfo();
        info.setCode(HttpStatus.SUCCESS);
        info.setMsg("查询成功");

        // 2: 获取当前登录用户的 username
        String username = SecurityUtils.getUsername();

        // 3: 基于当前登录用户, 去查询该用户为候选人/负责人的任务数量
        long total;
        if (carPackageAudit.getParams().get("beginCreateTime") == null) {
            total = taskService.createTaskQuery()
                    .taskCandidateOrAssigned(username)
                    .count();
        } else {
            total = taskService.createTaskQuery()
                    .taskCandidateOrAssigned(username)
                    .taskCreatedAfter(DateUtils.dateTime(DateUtils.YYYY_MM_DD, carPackageAudit.getParams().get("beginCreateTime") + ""))  // 在给定时间之后
                    .taskCreatedBefore(DateUtils.dateTime(DateUtils.YYYY_MM_DD, carPackageAudit.getParams().get("endCreateTime") + ""))   // 在给定时间之前
                    .count();
        }

        info.setTotal(total);
        // 4: 如果数量为 0, 直接返回空数据
        if (total == 0) {
            info.setRows(Collections.emptyList());
            return info;
        }

        // 1: 接收前段的分页条件
        PageDomain pageDomain = TableSupport.buildPageRequest();
        // 计算分页开始索引位置 (当前页 - 1) * 每页显示数量
        int startIndex = (pageDomain.getPageNum() - 1) * pageDomain.getPageSize();

        // 5: 基于当前登录用户, 去查询该用户为候选人/负责人的任务列表
        List<Task> taskList;
        if (carPackageAudit.getParams().get("beginCreateTime") != null) {
            taskList = taskService.createTaskQuery()
                    .taskCandidateOrAssigned(username)
                    .taskCreatedAfter(DateUtils.dateTime(DateUtils.YYYY_MM_DD, carPackageAudit.getParams().get("beginCreateTime") + ""))  // 在给定时间之后
                    .taskCreatedBefore(DateUtils.dateTime(DateUtils.YYYY_MM_DD, carPackageAudit.getParams().get("endCreateTime") + ""))   // 在给定时间之前
                    .orderByTaskCreateTime().asc()
                    .listPage(startIndex, pageDomain.getPageSize());
        } else {
            taskList = taskService.createTaskQuery()
                    .taskCandidateOrAssigned(username)
                    .orderByTaskCreateTime().asc()
                    .listPage(startIndex, pageDomain.getPageSize());
        }

        List<CarPackageAudit> list = new ArrayList<>();
        // 6: 遍历任务列表
        for (Task task : taskList) {
            // 7: 获取该任务的 流程实例ID. 查询流程实例对象,得到业务标识
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                    .processInstanceId(task.getProcessInstanceId())
                    .singleResult();
            // 7.1: 得到业务标识
            String businessKey = processInstance.getBusinessKey();

            // 8: 通过业务标识, 查询审核记录对象
            CarPackageAudit audit = carPackageAuditService.getById(Long.valueOf(businessKey));
            CarPackageAuditVo vo = new CarPackageAuditVo();
            BeanUtils.copyBeanProp(vo, audit); // 把 audit 字段的值复制给 vo(前提是必须字段名一样)

            // 查询创建人
            SysUser sysUser = userService.selectUserById(Long.parseLong(audit.getCreatorId()));
            vo.setCreator(sysUser);

            // 9: 为审核记录设置当前任务名称/id & 当前审核人
            vo.setTaskId(task.getId());
            vo.setTaskName(task.getName());
            // 通过 任务Key 查询候选人
            List<SysUser> userList = bpmnNodeService.selectUsersByNodeKey(task.getTaskDefinitionKey());
            // 把 获选人对象集合 转为候选人昵称集合
            List<String> nickNameList = userList.stream().map(SysUser::getNickName).collect(Collectors.toList());
            vo.setAuditors(JSON.toJSONString(nickNameList));

            // 10: 把当前审核记录对象放入返回的集合中
            list.add(vo);
        }

        // 11: 最终返回审核记录到列表集合
        info.setRows(list);
        return info;
    }
}
